<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日志管理系统</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#6B7280',
                        success: '#10B981',
                        warning: '#F59E0B',
                        danger: '#EF4444',
                        dark: '#1F2937',
                        light: '#F3F4F6'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .log-container {
                height: calc(100vh - 200px);
            }
            .log-line {
                white-space: pre-wrap;
                word-break: break-all;
            }
            .pulse-animation {
                animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
            }
            @keyframes pulse {
                0%, 100% {
                    opacity: 1;
                }
                50% {
                    opacity: 0.5;
                }
            }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans">
    <div class="container mx-auto px-4 py-8 max-w-7xl">
        <header class="mb-8">
            <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark mb-2">
                <i class="fa fa-file-text-o text-primary mr-2"></i>日志管理系统
            </h1>
            <p class="text-secondary">查看和下载应用程序日志文件</p>
        </header>

        <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
            <!-- 日志级别列表 -->
            <div class="lg:col-span-1 bg-white rounded-lg shadow-md overflow-hidden">
                <div class="p-4 bg-primary text-white">
                    <h2 class="font-semibold text-lg">
                        <i class="fa fa-tags mr-2"></i>日志级别
                    </h2>
                </div>
                <div class="p-4">
                    <ul id="levelList" class="space-y-1">
                        <!-- 日志级别将通过JavaScript动态加载 -->
                        <li class="flex justify-center p-8 text-gray-500">
                            <i class="fa fa-circle-o-notch fa-spin mr-2"></i>加载日志级别中...
                        </li>
                    </ul>
                </div>
            </div>

            <!-- 日志文件列表 -->
            <div class="lg:col-span-1 bg-white rounded-lg shadow-md overflow-hidden">
                <div class="p-4 bg-primary text-white">
                    <h2 class="font-semibold text-lg">
                        <i class="fa fa-folder-open mr-2"></i>日志文件列表
                    </h2>
                </div>
                <div class="p-4 max-h-[calc(100vh-240px)] overflow-y-auto">
                    <div class="mb-4 relative">
                        <input 
                            type="text" 
                            id="fileFilter" 
                            placeholder="搜索日志文件..." 
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50"
                            disabled
                        >
                        <i class="fa fa-search absolute right-3 top-3 text-gray-400"></i>
                    </div>
                    <ul id="fileList" class="space-y-1">
                        <!-- 日志文件列表将通过JavaScript动态加载 -->
                        <li class="flex justify-center p-8 text-gray-500">
                            <p>请先选择左侧日志级别</p>
                        </li>
                    </ul>
                </div>
            </div>

            <!-- 日志内容显示 -->
            <div class="lg:col-span-2 bg-white rounded-lg shadow-md overflow-hidden">
                <div class="p-4 bg-gray-800 text-white flex justify-between items-center">
                    <h2 class="font-semibold text-lg">
                        <i class="fa fa-file-text mr-2"></i><span id="currentFileName">请选择日志文件</span>
                    </h2>
                    <div>
                        <button id="downloadBtn" class="bg-primary hover:bg-primary/90 text-white px-4 py-2 rounded-lg mr-2 disabled:opacity-50 disabled:cursor-not-allowed transition" disabled>
                            <i class="fa fa-download mr-1"></i>下载
                        </button>
                        <button id="refreshBtn" class="bg-gray-600 hover:bg-gray-500 text-white px-4 py-2 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed transition" disabled>
                            <i class="fa fa-refresh mr-1"></i>刷新
                        </button>
                    </div>
                </div>
                <div id="logContentContainer" class="p-4 log-container overflow-y-auto bg-gray-900 text-gray-100 font-mono text-sm">
                    <div class="flex justify-center items-center h-full text-gray-400">
                        <div class="text-center">
                            <i class="fa fa-file-text-o text-5xl mb-4"></i>
                            <p>选择日志文件查看内容</p>
                        </div>
                    </div>
                </div>
                <div class="p-4 bg-gray-100 text-sm text-secondary flex justify-between">
                    <div>
                        <span id="logStats">未选择文件</span>
                    </div>
                    <div>
                        <select id="logLevelFilter" class="bg-white border border-gray-300 rounded px-2 py-1 text-sm" disabled>
                            <option value="all">所有级别</option>
                            <option value="INFO">INFO</option>
                            <option value="WARN">WARN</option>
                            <option value="ERROR">ERROR</option>
                            <option value="FATAL">FATAL</option>
                        </select>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // API基础地址，根据实际情况修改
        const API_BASE_URL = 'https://localhost:7081/api/logs';
        let currentLevel = null;  // 当前选中的日志级别
        let currentFile = null;   // 当前选中的日志文件
        
        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', () => {
            loadLogLevels();
            
            // 绑定事件
            document.getElementById('fileFilter').addEventListener('input', filterFiles);
            document.getElementById('refreshBtn').addEventListener('click', loadCurrentLogFile);
            document.getElementById('logLevelFilter').addEventListener('change', filterLogByLevel);
        });
        
        /**
         * 加载日志级别列表
         */
        async function loadLogLevels() {
            try {
                const response = await fetch(`${API_BASE_URL}/levels`);
                
                if (!response.ok) {
                    throw new Error(`HTTP错误，状态码: ${response.status}`);
                }
                
                const levels = await response.json();
                
                // 验证返回数据格式
                if (!Array.isArray(levels)) {
                    throw new Error('日志级别数据格式不正确');
                }
                
                renderLogLevels(levels);
            } catch (error) {
                document.getElementById('levelList').innerHTML = `
                    <li class="p-4 text-danger text-center">
                        <i class="fa fa-exclamation-circle mr-1"></i>${error.message || '获取日志级别失败'}
                    </li>
                `;
                console.error('加载日志级别失败:', error);
            }
        }
        
        /**
         * 渲染日志级别列表
         */
        function renderLogLevels(levels) {
            const levelListElement = document.getElementById('levelList');
            
            if (levels.length === 0) {
                levelListElement.innerHTML = `
                    <li class="p-4 text-center text-gray-500">
                        <i class="fa fa-info-circle mr-1"></i>没有找到日志级别
                    </li>
                `;
                return;
            }
            
            let html = '';
            levels.forEach(level => {
                // 确保level是对象且包含Level属性
                debugger;
                const levelName = level && typeof level === 'object' && level.level 
                    ? String(level.level)  // 强制转换为字符串
                    : '未知级别';
                
                html += `
                    <li>
                        <button 
                            class="level-btn w-full text-left px-3 py-2 rounded hover:bg-gray-100 transition flex items-center"
                            data-level="${levelName}"
                        >
                            <i class="fa fa-tag text-primary mr-2"></i>
                            <span>${levelName}</span>
                        </button>
                    </li>
                `;
            });
            
            levelListElement.innerHTML = html;
            
            // 绑定级别点击事件
            document.querySelectorAll('.level-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    // 移除其他级别的选中状态
                    document.querySelectorAll('.level-btn').forEach(b => {
                        b.classList.remove('bg-primary/10', 'font-medium');
                    });
                    
                    // 添加当前级别的选中状态
                    btn.classList.add('bg-primary/10', 'font-medium');
                    
                    // 获取并存储当前选中的级别（确保是字符串类型）
                    currentLevel = String(btn.getAttribute('data-level'));
                    
                    // 重置文件列表和内容
                    resetFileAndContent();
                    
                    // 加载该级别下的日志文件
                    loadLogFiles(currentLevel);
                });
            });
        }
        
        /**
         * 加载指定级别下的日志文件
         */
        async function loadLogFiles(level) {
            // 参数验证
            if (!level || typeof level !== 'string') {
                console.error('无效的日志级别:', level);
                return;
            }
            
            const fileListElement = document.getElementById('fileList');
            const fileFilter = document.getElementById('fileFilter');
            
            // 显示加载状态
            fileListElement.innerHTML = `
                <li class="flex justify-center p-8 text-gray-500">
                    <i class="fa fa-circle-o-notch fa-spin mr-2"></i>加载日志文件中...
                </li>
            `;
            fileFilter.disabled = true;
            
            try {
                const response = await fetch(`${API_BASE_URL}/files/${encodeURIComponent(level)}`);
                
                if (!response.ok) {
                    throw new Error(`获取日志文件失败，状态码: ${response.status}`);
                }
                
                const files = await response.json();
                
                // 验证返回数据格式
                if (!Array.isArray(files)) {
                    throw new Error('日志文件数据格式不正确');
                }
                
                // 启用文件过滤器
                fileFilter.disabled = false;
                
                renderLogFiles(files);
            } catch (error) {
                fileListElement.innerHTML = `
                    <li class="p-4 text-danger text-center">
                        <i class="fa fa-exclamation-circle mr-1"></i>${error.message || '获取日志文件失败'}
                    </li>
                `;
                console.error('加载日志文件失败:', error);
            }
        }
        
        /**
         * 渲染日志文件列表
         */
        function renderLogFiles(files) {
            const fileListElement = document.getElementById('fileList');
            
            if (files.length === 0) {
                fileListElement.innerHTML = `
                    <li class="p-4 text-center text-gray-500">
                        <i class="fa fa-info-circle mr-1"></i>该级别下没有日志文件
                    </li>
                `;
                return;
            }
            
            let html = '';
            files.forEach(file => {
                // 格式化文件大小和时间
                const fileSize = file.fileSizeDisplay || formatFileSize(file.fileSize || 0);
                const lastWriteTime = file.lastWriteTime 
                    ? new Date(file.lastWriteTime).toLocaleString() 
                    : '未知时间';
                
                html += `
                    <li>
                        <button 
                            class="log-file-btn w-full text-left px-3 py-2 rounded hover:bg-gray-100 transition flex flex-col sm:flex-row sm:justify-between sm:items-center"
                            data-filename="${file.fileName || ''}"
                        >
                            <div class="flex items-center">
                                <i class="fa fa-file-text-o text-primary mr-2"></i>
                                <span class="truncate max-w-[200px] sm:max-w-none">${file.fileName || '未知文件'}</span>
                            </div>
                            <div class="text-xs text-gray-500 mt-1 sm:mt-0">
                                ${fileSize} · ${lastWriteTime}
                            </div>
                        </button>
                    </li>
                `;
            });
            
            fileListElement.innerHTML = html;
            
            // 绑定文件点击事件
            document.querySelectorAll('.log-file-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    // 移除其他文件的选中状态
                    document.querySelectorAll('.log-file-btn').forEach(b => {
                        b.classList.remove('bg-primary/10', 'font-medium');
                    });
                    
                    // 添加当前文件的选中状态
                    btn.classList.add('bg-primary/10', 'font-medium');
                    
                    const fileName = btn.getAttribute('data-filename');
                    loadLogFileContent(currentLevel, fileName);
                });
            });
        }
        
        /**
         * 过滤文件列表
         */
        function filterFiles() {
            const filterText = (document.getElementById('fileFilter').value || '').toLowerCase();
            const fileButtons = document.querySelectorAll('.log-file-btn');
            
            fileButtons.forEach(btn => {
                const fileName = (btn.getAttribute('data-filename') || '').toLowerCase();
                if (fileName.includes(filterText)) {
                    btn.parentElement.style.display = '';
                } else {
                    btn.parentElement.style.display = 'none';
                }
            });
        }
        
        /**
         * 加载日志文件内容
         */
        async function loadLogFileContent(level, fileName) {
            // 参数验证
            if (!level || typeof level !== 'string' || !fileName || typeof fileName !== 'string') {
                console.error('无效的日志级别或文件名:', level, fileName);
                return;
            }
            
            currentFile = fileName;
            const contentContainer = document.getElementById('logContentContainer');
            const currentFileNameElement = document.getElementById('currentFileName');
            const downloadBtn = document.getElementById('downloadBtn');
            const refreshBtn = document.getElementById('refreshBtn');
            const logLevelFilter = document.getElementById('logLevelFilter');
            
            // 更新UI状态
            currentFileNameElement.textContent = fileName;
            contentContainer.innerHTML = `
                <div class="flex justify-center items-center h-full text-gray-400">
                    <i class="fa fa-circle-o-notch fa-spin mr-2"></i>加载日志内容中...
                </div>
            `;
            downloadBtn.disabled = false;
            refreshBtn.disabled = false;
            logLevelFilter.disabled = false;
            
            try {
                const response = await fetch(`${API_BASE_URL}/content/${encodeURIComponent(level)}/${encodeURIComponent(fileName)}`);
                
                if (!response.ok) {
                    throw new Error(`获取日志内容失败，状态码: ${response.status}`);
                }
                
                const data = await response.json();
                debugger;
                if (typeof data.content !== 'string') {
                    throw new Error('日志内容格式不正确');
                }
                
                renderLogContent(data.content);
                
                // 更新下载按钮事件
                downloadBtn.onclick = () => {
                    window.location.href = `${API_BASE_URL}/download/${encodeURIComponent(level)}/${encodeURIComponent(fileName)}`;
                };
                
            } catch (error) {
                contentContainer.innerHTML = `
                    <div class="p-4 text-danger text-center">
                        <i class="fa fa-exclamation-circle mr-1"></i>${error.message || '读取日志内容失败'}
                    </div>
                `;
                console.error('加载日志内容失败:', error);
            }
        }
        
        /**
         * 重新加载当前日志文件
         */
        function loadCurrentLogFile() {
            if (currentLevel && currentFile) {
                loadLogFileContent(currentLevel, currentFile);
            }
        }
        
        /**
         * 渲染日志内容
         */
        function renderLogContent(content) {
            const contentContainer = document.getElementById('logContentContainer');
            
            if (!content) {
                contentContainer.innerHTML = `
                    <div class="text-center p-4 text-gray-400">
                        <i class="fa fa-info-circle mr-1"></i>日志文件为空
                    </div>
                `;
                updateLogStats(0);
                return;
            }
            
            // 按行拆分日志
            const lines = content.split('\n');
            let html = '';
            
            lines.forEach(line => {
                // 确保line是字符串
                const lineStr = String(line);
                let levelClass = '';
                
                // 检查日志级别并添加样式（修复核心错误点：确保使用字符串方法）
                if (lineStr.includes('ERROR') || lineStr.includes('FATAL')) {
                    levelClass = 'text-danger';
                } else if (lineStr.includes('WARN')) {
                    levelClass = 'text-warning';
                } else if (lineStr.includes('INFO')) {
                    levelClass = 'text-success';
                }
                
                html += `<div class="log-line ${levelClass} mb-1">${escapeHtml(lineStr)}</div>`;
            });
            
            contentContainer.innerHTML = html;
            updateLogStats(lines.length);
        }
        
        /**
         * 按日志级别过滤
         */
        function filterLogByLevel() {
            const selectedLevel = document.getElementById('logLevelFilter').value;
            const logLines = document.querySelectorAll('.log-line');
            
            if (selectedLevel === 'all') {
                logLines.forEach(line => {
                    line.style.display = '';
                });
                return;
            }
            
            // 确保selectedLevel是字符串
            const levelStr = String(selectedLevel).toUpperCase();
            
            logLines.forEach(line => {
                const lineText = String(line.textContent);
                if (lineText.includes(levelStr)) {
                    line.style.display = '';
                } else {
                    line.style.display = 'none';
                }
            });
        }
        
        /**
         * 更新日志统计信息
         */
        function updateLogStats(lineCount) {
            const logStatsElement = document.getElementById('logStats');
            logStatsElement.textContent = `共 ${lineCount} 行日志`;
        }
        
        /**
         * 格式化文件大小
         */
        function formatFileSize(bytes) {
            if (typeof bytes !== 'number' || isNaN(bytes) || bytes < 0) {
                return '0 B';
            }
            
            if (bytes < 1024) {
                return `${bytes} B`;
            } else if (bytes < 1024 * 1024) {
                return `${(bytes / 1024).toFixed(2)} KB`;
            } else if (bytes < 1024 * 1024 * 1024) {
                return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
            } else {
                return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
            }
        }
        
        /**
         * HTML转义，防止XSS攻击
         */
        function escapeHtml(unsafe) {
            if (typeof unsafe !== 'string') {
                return '';
            }
            return unsafe
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
        }
        
        /**
         * 重置文件列表和内容
         */
        function resetFileAndContent() {
            document.getElementById('fileList').innerHTML = `
                <li class="flex justify-center p-8 text-gray-500">
                    <i class="fa fa-circle-o-notch fa-spin mr-2"></i>加载日志文件中...
                </li>
            `;
            document.getElementById('logContentContainer').innerHTML = `
                <div class="flex justify-center items-center h-full text-gray-400">
                    <div class="text-center">
                        <i class="fa fa-file-text-o text-5xl mb-4"></i>
                        <p>选择日志文件查看内容</p>
                    </div>
                </div>
            `;
            document.getElementById('currentFileName').textContent = '请选择日志文件';
            document.getElementById('downloadBtn').disabled = true;
            document.getElementById('refreshBtn').disabled = true;
            document.getElementById('logLevelFilter').disabled = true;
            document.getElementById('logStats').textContent = '未选择文件';
            document.getElementById('fileFilter').value = '';
            currentFile = null;
        }
    </script>
</body>
</html>
    